package com.example.performance.r2dbc.entity.performance;

import com.example.performance.r2dbc.entity.RecordDb;
import lombok.NonNull;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.example.performance.r2dbc.entity.performance.RecordSetUtil.*;

/**
 * @author ShiSheng Gao
 * @since 2023/04/17
 */

public class VisibleRecordRowMapperByEnumAndIndex implements RowMapper<RecordDb> {

    private final List<String> visibleFields;

    public VisibleRecordRowMapperByEnumAndIndex(List<String> visibleFields) {
        this.visibleFields = visibleFields;
    }

    @Override
    public @NonNull RecordDb mapRow(@NonNull ResultSet rs, int rowNum) throws SQLException {
        return from(rs);
    }

    private RecordDb from(ResultSet rs) throws SQLException {
        RecordDb.RecordDbBuilder builder = RecordDb.builder();

        builder.id(getLong(rs, 1));
        builder.nodeId(getLong(rs, 2));
        builder.statut(getStatus(rs, 3));

        for (int i = 0; i < visibleFields.size(); i++) {

            String columnName = visibleFields.get(i);
            int columnIndex = i + 4;

            switch (getDdsFieldId(columnName)) {
                case ID_COMMANDE -> builder.commandeId(getString(rs, columnIndex));
                case ID_CLIENT -> builder.clientId(getString(rs, columnIndex));
                case QTE_COMMANDE -> builder.commandQty(getDouble(rs, columnIndex));
                case DATE_EXPED_DEMAND -> builder.expedDemand(getLong(rs, columnIndex));
                case DATE_DLUO -> builder.dluo(getLong(rs, columnIndex));
                case DATE_PROD -> builder.prod(getLong(rs, columnIndex));
                case QTE_LIVRE -> builder.livre(getDouble(rs, columnIndex));
                case DATE_LIVRAISON -> builder.livraison(getLong(rs, columnIndex));
                case DATE_PROD_INIT -> builder.prodInit(getLong(rs, columnIndex));
                case QTE_RELIQUAT -> builder.reliquat(getDouble(rs, columnIndex));

                case TEXT1 -> builder.text1(getString(rs, columnIndex));
                case TEXT2 -> builder.text2(getString(rs, columnIndex));
                case TEXT3 -> builder.text3(getString(rs, columnIndex));
                case TEXT4 -> builder.text4(getString(rs, columnIndex));
                case TEXT5 -> builder.text5(getString(rs, columnIndex));
                case TEXT6 -> builder.text6(getString(rs, columnIndex));
                case TEXT7 -> builder.text7(getString(rs, columnIndex));
                case TEXT8 -> builder.text8(getString(rs, columnIndex));
                case TEXT9 -> builder.text9(getString(rs, columnIndex));
                case TEXT10 -> builder.text10(getString(rs, columnIndex));

                case QTY1 -> builder.qty1(getDouble(rs, columnIndex));
                case QTY2 -> builder.qty2(getDouble(rs, columnIndex));
                case QTY3 -> builder.qty3(getDouble(rs, columnIndex));
                case QTY4 -> builder.qty4(getDouble(rs, columnIndex));
                case QTY5 -> builder.qty5(getDouble(rs, columnIndex));
                case QTY6 -> builder.qty6(getDouble(rs, columnIndex));
                case QTY7 -> builder.qty7(getDouble(rs, columnIndex));
                case QTY8 -> builder.qty8(getDouble(rs, columnIndex));
                case QTY9 -> builder.qty9(getDouble(rs, columnIndex));
                case QTY10 -> builder.qty10(getDouble(rs, columnIndex));

                case DATE1 -> builder.date1(getLong(rs, columnIndex));
                case DATE2 -> builder.date2(getLong(rs, columnIndex));
                case DATE3 -> builder.date3(getLong(rs, columnIndex));
                case DATE4 -> builder.date4(getLong(rs, columnIndex));
                case DATE5 -> builder.date5(getLong(rs, columnIndex));
                case DATE6 -> builder.date6(getLong(rs, columnIndex));
                case DATE7 -> builder.date7(getLong(rs, columnIndex));
                case DATE8 -> builder.date8(getLong(rs, columnIndex));
                case DATE9 -> builder.date9(getLong(rs, columnIndex));
                case DATE10 -> builder.date10(getLong(rs, columnIndex));

                default -> { // ignore rest and unrecognized columns
                }
            }

        }

        return builder.build();
    }

    private static DDSFieldId getDdsFieldId(String columnName) {
        return DDSFieldId.valueOf(columnName);
    }

    private static DDSFieldId getDdsFieldId2(String columnName) {
        return map.get(columnName);
    }

    static Map<String, DDSFieldId> map = Arrays.stream(DDSFieldId.values())
            .collect(Collectors.toMap(
                    Enum::name,
                    ddsFieldId -> ddsFieldId
            ));

}
